package com.yy.springcloud.mq;

import com.yy.kit.log.YYLogKits;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.UUID;

/**
 * <p>
 * 消息生产者：
 * 实现ConfirmCallback 接口用于实现消息发送到RabbitMQ交换器后接收ack回调
 * 实现ReturnCallback接口用于实现消息发送到RabbitMQ交换器，但无相应队列与交换器绑定时的回调
 * </p>
 *
 * @author 杨阳
 * @since 2017年12月11日
 */
@Component
public class Sender implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if (ack) {
            YYLogKits.printImportant(this.getClass(), "发送消息成功：{}", correlationData);
        } else {
            YYLogKits.printException(this.getClass(), "发送消息失败：{}" + cause);
        }
    }

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        YYLogKits.printException(this.getClass(), "{}发送失败!", message.getMessageProperties().getCorrelationIdString());
    }

    /**
     * <p>
     * 使用Queue发送消息
     * </p>
     *
     * @param msg 消息内容
     */
    public void sendByQueue(String msg) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        YYLogKits.info(this.getClass(), "开始发送消息：{}", msg);
        String response = rabbitTemplate.convertSendAndReceive(
                Params.EXCHANGE, Params.ROUTKEY, msg, correlationData).toString();
        YYLogKits.info(this.getClass(), "发送消息完成：{}", msg);
        YYLogKits.info(this.getClass(), "消费者响应：{}消息，处理完成!", response);
    }

    /**
     * <p>
     * 使用Exchange发送消息
     * </p>
     *
     * @param msg 消息内容
     */
    public void sendByExchange(String msg) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        YYLogKits.info(this.getClass(), "开始发送消息：{}", msg);
        String response = rabbitTemplate.convertSendAndReceive(
                Params.EXCHANGE, Params.ROUTKEY2, msg, correlationData).toString();
        YYLogKits.info(this.getClass(), "发送消息完成：{}", msg);
        YYLogKits.info(this.getClass(), "消费者响应：{}消息，处理完成!", response);
    }
}
